package com.multimedia.scala.sudoku

object Solver {
	var tries = 0
    def solve(data: List[List[Int]]): List[List[Int]] = {
        return solve(data, 0, 0, "")
    }
	
	def solve(data: List[List[Int]], row: Int, col: Int, chosen: String): List[List[Int]] = {
        tries += 1
        //println("num: "+ tries)
    	//println("iteration:["+row+"] ["+col+"]"+chosen)
    	//if (tries>=14)
    	//    return data
	    var coords = getNextZeroPosition(data, row, col)
    	if (coords!=null && hasMoreCells(row, col)) {
            var numbers = Field.possibleNumbers(data, coords._1, coords._2)

            if (numbers.isEmpty) {
                //println ("numbers empty skipping")
                return null
            }
            numbers.foreach(el => {
            	  var rez = data
            	  var tmp = data.updated(coords._1, data(coords._1).updated(coords._2, el))
            	  
            	  if (coords._2 > 7) {
            		  rez = solve(tmp, coords._1 + 1, 0, chosen + el)
            	  } else {
            	      rez = solve(tmp, coords._1, coords._2 + 1, chosen + el)
            	  }
            	  if (rez!=null) {
            		  return rez
            	  }
            })
	        
    		return null
    	} else {
    	    if (Checker.checkField(data)) {
    	    	return data
    	    } else {
    	        return null
    	    }
    	}
	}
    /** checks whether there anymore undefined elements */
    private def hasZeros(data: List[List[Int]]): Boolean = !data.forall(l => l.forall(_!=0))
    private def hasMoreCells(row: Int, col: Int): Boolean = row<=8||col<=8

    private def getNextZeroPosition(data: List[List[Int]], row: Int, col: Int): (Int, Int) = {
        var i = row
        var j = col
        while (i<9) {
        	if (j==9) {
        	    i = i + 1
        	    j = 0
        	}
            if (data(i)(j)==0)
                return (i, j)
            j = j + 1
        }
        return null
    }
}